package com.wisdytech.linkdcs.tool.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pagehelper.PageInfo;
import com.wisdytech.common.bean.Filter;
import com.wisdytech.common.constants.CommonConstants;
import com.wisdytech.common.exception.ServiceException;
import com.wisdytech.common.handler.BaseService;
import com.wisdytech.common.utils.BaseUtil;
import com.wisdytech.common.utils.ImportExcelUtils;
import com.wisdytech.linkdcs.equipment.dao.IEqModelDao;
import com.wisdytech.linkdcs.equipment.dao.IModelOperationDao;
import com.wisdytech.linkdcs.equipment.model.EquipModel;
import com.wisdytech.linkdcs.equipment.model.ModelOperation;
import com.wisdytech.linkdcs.system.model.SysUser;
import com.wisdytech.linkdcs.tool.dao.EqToolConfigDao;
import com.wisdytech.linkdcs.tool.dao.ToolConfigDao;
import com.wisdytech.linkdcs.tool.dao.ToolReplaceRecordDao;
import com.wisdytech.linkdcs.tool.dao.TtEqToolDao;
import com.wisdytech.linkdcs.tool.model.EqToolConfig;
import com.wisdytech.linkdcs.tool.model.ToolConfig;
import com.wisdytech.linkdcs.tool.model.ToolReplaceRecord;
import com.wisdytech.linkdcs.tool.model.TtEqTool;
import com.wisdytech.linkdcs.tool.service.IToolConfigService;
import com.wisdytech.linkdcs.tool.vo.ToolConfigVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhanghailin
 * @since 2018-06-06
 */
@Service
@Transactional
public class ToolConfigServiceImpl extends BaseService<ToolConfigDao, ToolConfig> implements IToolConfigService {

    @Resource
    private ToolConfigDao toolConfigDao;

    @Resource
    private TtEqToolDao ttEqToolDao;

    @Resource
    private IEqModelDao eqModelDao;
    @Resource
    private IModelOperationDao iModelOperationDao;

    @Resource
    private ToolReplaceRecordDao toolReplaceRecordDao;
    @Resource
    private EqToolConfigDao eqToolConfigDao;
    @Override
    public PageInfo<ToolConfigVO> getToolConfigByFilter(String modelCode, Filter filter) {
        if(StringUtils.isBlank(modelCode))
            return new PageInfo<>(new ArrayList<>());
        List<ToolConfigVO> list = this.beforeList(ToolConfigDao.class,filter).getToolConfigByFilter(modelCode);
        return new PageInfo<>(list);
    }

    @Override
    public ToolConfigVO getToolConfigInfo(String modelCode) {
        ToolConfigVO vo = new ToolConfigVO();
        if(StringUtils.isBlank(modelCode)) {
            return null;
        }
        EquipModel queryParams = new EquipModel();
        queryParams.setModelCode(modelCode);
        queryParams.setDelFlag(CommonConstants.DEL_FLAG);
        EquipModel eqModel = eqModelDao.selectOne(queryParams);
        vo.setModelId(eqModel.getPkId());
        vo.setModelCode(eqModel.getModelCode());
        List<Map<String, Object>> opMap = this.toolConfigDao.getOperationByEqModel(modelCode);
        vo.setOperation(opMap);
        return vo;
    }

    /**
     * 根据设备型号删选工装信息（主要是为了select2下拉框使用）
     * @param search 模糊搜索toolCode
     * @param modelCode 设备型号主键
     * @param toolCode 设备型号主键
     * @param filter 分页参数
     * @return pageinfo
     */
    @Override
    public PageInfo<ToolConfigVO> getToolListByFilter(String search, String modelCode, String toolCode, Filter filter) {
        if(StringUtils.isBlank(modelCode))
            return new PageInfo<>(new ArrayList<>());
        Map<String, Object> params = new HashMap<>();
        if(StringUtils.isNotBlank(search)) {
            params.put("toolCode", search);
        }
        if(StringUtils.isNotBlank(toolCode)) {
            params.put("toolCodeExclude", toolCode);
        }

        params.put("modelCode",modelCode);
        //如果改设备型号下没有工序，则列出所有的工装
        List<Map<String, Object>> opList = this.toolConfigDao.getOperationByEqModel(modelCode);
        List<ToolConfigVO> list;
        if(opList!=null&&opList.size()==0) {
             list = this.beforeList(ToolConfigDao.class,filter).getAllTool(params);
        } else {
            list = this.beforeList(ToolConfigDao.class,filter).getToolByEqModel(params);
        }
        PageInfo<ToolConfigVO> page = new PageInfo<>(list);
        return page;
    }



    @Override
    @Transactional
    public Boolean saveOrUpdateToolConfig(ToolConfig toolConfig, SysUser operator) {
        Boolean flag = false;
        if(operator == null)
            throw new ServiceException("操作人不能为空");
        if(toolConfig == null||StringUtils.isBlank(toolConfig.getModelCode())||StringUtils.isBlank(toolConfig.getToolCode()))
            throw new ServiceException("参数错误");
        TtEqTool params = new TtEqTool();
        params.setDelFlag(CommonConstants.DEL_FLAG);
        params.setToolCode(toolConfig.getToolCode());
        TtEqTool tool = this.ttEqToolDao.selectOne(params);
        if(tool == null)
            throw new ServiceException("工装不能为空");
        if(!"1".equals(tool.getStatus())) {
            throw  new ServiceException("工装状态不可用");
        }
        EntityWrapper<ToolConfig> ew = new EntityWrapper<>();
        ew.eq("tool_code",toolConfig.getToolCode())
                .eq("model_code",toolConfig.getModelCode())
                .eq("del_flag",CommonConstants.DEL_FLAG);
        //修改情况下校验重复性除去自身
        if(StringUtils.isNotBlank(toolConfig.getPkId())) {
            ew.ne("pk_id",toolConfig.getPkId());
        }
        Integer count = toolConfigDao.selectCount(ew);
        if(count>0) {
            throw new ServiceException("工装配置重复");
        }
        Boolean includeOp = false;
        //校验工序（工装的工序需要属于设备型号下设备拥有的工序，否则更新失败）
        List<Map<String, Object>> opMap = this.toolConfigDao.getOperationByEqModel(toolConfig.getModelCode());
        for (Map<String, Object> map: opMap) {
            if(StringUtils.isNotBlank(toolConfig.getUsedOperation())&&toolConfig.getUsedOperation().equals(map.get("pkId")+"")){
                includeOp = true;
            }
        }
        if(!includeOp&&opMap.size()>0) {
            throw new ServiceException("工序错误");
        }
        //修改
        if(StringUtils.isNotBlank(toolConfig.getPkId())) {
            toolConfig.setUpdateUser(operator.getUsername());
            toolConfig.setUpdateDate(new Date());
            Integer updateCount = toolConfigDao.updateById(toolConfig);
            if(updateCount > 0)
                flag = true;
        } else {
        //新增
            toolConfig.setPkId(BaseUtil.getUUID());
            toolConfig.setCreateDate(new Date());
            toolConfig.setDelFlag(CommonConstants.DEL_FLAG);
            toolConfig.setCreateUser(operator.getUsername());
            Integer insertCount = toolConfigDao.insert(toolConfig);
            if(insertCount > 0)
                flag = true;
        }
        //更新工装状态 为使用中
        /*if (flag) {
            tool.setStatus("1");
            ttEqToolDao.updateToolStatus(tool);
        }*/

        return flag;
    }

    @Override
    public Boolean deleteToolConfig(String pkIds, SysUser operator) {
        if(operator == null)
            throw new ServiceException("操作人不能为空!");
        String[] deletePkIds = pkIds.split(",");
        if(deletePkIds.length == 0) return true;
        for(String id: deletePkIds){
            //获取配置信息
            ToolConfig toolConfig = toolConfigDao.selectById(id);
            EntityWrapper<EqToolConfig> ew1 = new EntityWrapper();
            ew1.eq("TOOL_CODE",toolConfig.getToolCode());
            ew1.eq("DEL_FLAG",CommonConstants.DEL_FLAG);
            List<EqToolConfig> list1 = eqToolConfigDao.selectList(ew1);
            if(!list1.isEmpty()){
                throw new ServiceException("该工装已存在更换");
            }
            //通用工装编码获取该工装更换的记录
            EntityWrapper<ToolReplaceRecord> ew = new EntityWrapper<>();
            ew.eq("ORIGIN_TOOL_CODE",toolConfig.getToolCode());
            ew.eq("DEL_FLAG",CommonConstants.DEL_FLAG);
            List<ToolReplaceRecord> list =  toolReplaceRecordDao.selectList(ew);
            if(!list.isEmpty()){
                throw new ServiceException("该工装已存在更换");
            }
        }
        List<String> pkIdCollection = Arrays.asList(deletePkIds);
        Integer deleteCount = toolConfigDao.deleteBatchIds(pkIdCollection);
        return deleteCount > 0;
    }

    @Override
    public ToolConfigVO getToolConfigInfoById(String pkId) {
        if(StringUtils.isBlank(pkId))
            return null;
        ToolConfigVO vo = this.toolConfigDao.getToolConfigInfoById(pkId);
        if(vo!=null&&StringUtils.isNotBlank(vo.getModelCode())) {
            List<Map<String, Object>> opMap = this.toolConfigDao.getOperationByEqModel(vo.getModelCode());
            vo.setOperation(opMap);
        }
        return vo;
    }

	@Override
	public PageInfo<ToolConfigVO> getEquipToolListByFilter(String search, String equipCode, Filter filter) {
        if(StringUtils.isBlank(equipCode))
            return new PageInfo<>(new ArrayList<>());
        Map<String, Object> params = new HashMap<>();
        if(StringUtils.isNotBlank(search)) {
            params.put("toolCode", search);
        }
        params.put("equipCode",equipCode);
        List<ToolConfigVO> list = this.beforeList(ToolConfigDao.class,filter).getEquipToolListByFilter(params);
        PageInfo<ToolConfigVO> page = new PageInfo<>(list);
        return page;
	}

    @Override
    public void batchImportToolConfig(MultipartFile file, SysUser operator) {
        if (file == null) {
            throw new ServiceException("文件为空");
        }
        if (operator ==null) {
            throw new ServiceException("操作人不能为空");
        }
        int errorRow=0;
        try {
            String fileName = file.getOriginalFilename();
            InputStream in = file.getInputStream();
            List<List<Object>> data = ImportExcelUtils.getDataListByExcel(in, fileName);
            if (data == null || data.size() == 0) {
                throw new ServiceException("表格数据为空");
            }
            List<ToolConfig> list = new ArrayList<>();

            //i 从1开始，去除表头数据，根据自己的模板而定
            for (int i = 1; i < data.size(); i++) {
                errorRow = i;
                ToolConfig toolConfig = new ToolConfig();
                toolConfig.setCreateDate(new Date());
                toolConfig.setCreateUser(operator.getUsername());
                toolConfig.setDelFlag(CommonConstants.DEL_FLAG);
                toolConfig.setPkId(BaseUtil.getUUID());
                if (data.get(i).get(0) == null||StringUtils.isBlank(data.get(i).get(0).toString())) {
                    throw new ServiceException("第"+i+"行第1列设备型号数据不能为空");
                }
                if(!checkModelCode(data.get(i).get(0).toString())) {
                    throw new ServiceException("第"+i+"行第1列设备型号数据在数据库中不存在");
                }
                toolConfig.setModelCode(data.get(i).get(0).toString());

                if (data.get(i).get(1) == null||StringUtils.isBlank(data.get(i).get(1).toString())) {
                    throw new ServiceException("第"+i+"行第2列工装编码数据不能为空");
                }
                if (!checkToolCode(data.get(i).get(1).toString())) {
                    throw new ServiceException("第"+i+"行第2列工装编码数据在工装库中不存在");
                }
                if (checkToolCodeRepeat(toolConfig.getModelCode(),data.get(i).get(1).toString())) {
                    throw new ServiceException("第"+i+"行第2列工装编码数据重复");
                }
                toolConfig.setToolCode(data.get(i).get(1).toString());
                //TODO 批量插入 未做工序校验
                toolConfigDao.insert(toolConfig);
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException("上传文件出错");
        } catch (IndexOutOfBoundsException e2) {
            e2.printStackTrace();
            throw new ServiceException("表格中第"+errorRow+"存在空数据");
        }
    }

    private Boolean checkModelCode(String modelCode) {
        if (StringUtils.isBlank(modelCode)) {
            return false;
        }
        EntityWrapper<EquipModel> ew = new EntityWrapper<>();
        ew.eq("model_code",modelCode).eq("del_flag",CommonConstants.DEL_FLAG);
        return eqModelDao.selectCount(ew)>0;
    }

    private Boolean checkToolCode(String toolCode) {
        if (StringUtils.isBlank(toolCode)) {
            return false;
        }
        EntityWrapper<TtEqTool> ew = new EntityWrapper<>();
        ew.eq("tool_code",toolCode).eq("del_flag",CommonConstants.DEL_FLAG);
        return ttEqToolDao.selectCount(ew)>0;

    }

    private Boolean checkToolCodeRepeat(String modelCode,String toolCode) {
        if (StringUtils.isBlank(toolCode)||StringUtils.isBlank(modelCode)) {
            return false;
        }
        //获取设备型号工序
        List<ModelOperation> list = iModelOperationDao.listOperations(modelCode);
        TtEqTool t = new TtEqTool();
        t.setToolCode(toolCode);
        t.setDelFlag(CommonConstants.DEL_FLAG);
        TtEqTool ttEqTool = ttEqToolDao.selectOne(t);
        if(!list.isEmpty()){
            if(ttEqTool!=null){
                for(ModelOperation m : list){
                    if(!m.getOpCode().equals(ttEqTool.getOpCode())){
                        throw new ServiceException("该工装不包含该型号的工序");
                    }
                }
            }
        }
        EntityWrapper<ToolConfig> ew = new EntityWrapper<>();
        ew.eq("model_code",modelCode).eq("tool_code",toolCode).eq("del_flag",CommonConstants.DEL_FLAG);
        return toolConfigDao.selectCount(ew)>0;

    }
}
